home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Amiga
/
World of Amiga.iso
/
archive
/
3d
/
povray40.lha
/
src
/
targa.c
< prev
Wrap
C/C++ Source or Header
|
1992-10-22
|
8KB
|
289 lines
/****************************************************************************
* targa.c
*
* This module contains the code to read and write the Targa output file
* format.
*
* from Persistence of Vision Raytracer
* Copyright 1992 Persistence of Vision Team
*---------------------------------------------------------------------------
* Copying, distribution and legal info is in the file povlegal.doc which
* should be distributed with this file. If povlegal.doc is not available
* or for more info please contact:
*
* Drew Wells [POV-Team Leader]
* CIS: 73767,1244 Internet: 73767.1244@compuserve.com
* Phone: (213) 254-4041
*
* This program is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
*
*****************************************************************************/
#include "frame.h"
#include "povproto.h"
int Targa_Line_Number = 0;
extern int First_Line;
FILE_HANDLE *Get_Targa_File_Handle()
{
FILE_HANDLE *handle;
if ((handle = (FILE_HANDLE *) malloc(sizeof(FILE_HANDLE))) == NULL) {
fprintf (stderr, "Cannot allocate memory for output file handle\n");
return(NULL);
}
handle->Default_File_Name_p = Default_Targa_File_Name;
handle->Open_File_p = Open_Targa_File;
handle->Write_Line_p = Write_Targa_Line;
handle->Read_Line_p = Read_Targa_Line;
handle->Read_Image_p = Read_Targa_Image;
handle->Close_File_p = Close_Targa_File;
handle->file = NULL;
handle->buffer_size = 0;
handle->buffer = NULL;
return (handle);
}
char *Default_Targa_File_Name()
{
return ("data.tga");
}
int Open_Targa_File (handle, name, width, height, buffer_size, mode)
FILE_HANDLE *handle;
char *name;
int *width;
int *height;
int buffer_size;
int mode;
{
int data1, data2, i;
handle->mode = mode;
handle->filename = name;
switch (mode) {
case READ_MODE:
if ((handle->file = fopen (name, READ_FILE_STRING)) == NULL)
return(0);
if (buffer_size != 0) {
if ((handle->buffer = malloc (buffer_size)) == NULL)
return(0);
setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
}
for (i = 0 ; i < 12 ; i++)
if (getc(handle->file) == EOF)
return(0);
if (((data1 = getc(handle->file)) == EOF)
|| ((data2 = getc(handle->file)) == EOF))
return(0);
*width = data2 * 256 + data1;
if (((data1 = getc(handle->file)) == EOF)
|| ((data2 = getc(handle->file)) == EOF))
return(0);
for (i = 0 ; i < 2 ; i++)
if (getc(handle->file) == EOF)
return(0);
*height = data2 * 256 + data1;
handle->width = *width;
handle->height = *height;
handle->buffer_size = buffer_size;
break;
case WRITE_MODE:
if ((handle->file = fopen (name, WRITE_FILE_STRING)) == NULL)
return(0);
if (buffer_size != 0) {
if ((handle->buffer = malloc (buffer_size)) == NULL)
return(0);
setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
}
for (i = 0; i < 10; i++) /* 00, 00, 02, then 7 00's... */
if (i == 2)
putc(i, handle->file);
else
putc(0, handle->file);
putc((First_Line & 0xFF), handle->file); /* y origin set to "First_Line" */
putc(((First_Line >> 8) & 0xFF), handle->file);
putc((*width & 0xFF), handle->file); /* write width and height */
putc(((*width >> 8) & 0xFF), handle->file);
putc((*height & 0xFF), handle->file);
putc(((*height >> 8) & 0xFF), handle->file);
putc(24, handle->file); /* 24 bits/pixel (16 million col */
putc(32, handle->file); /* Bitmask, pertinent bit: top-d */
handle->width = *width;
handle->height = *height;
handle->buffer_size = buffer_size;
break;
case APPEND_MODE:
if ((handle->file = fopen (name, APPEND_FILE_STRING)) == NULL)
return(0);
if (buffer_size != 0) {
if ((handle->buffer = malloc (buffer_size)) == NULL)
return(0);
setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
}
break;
}
return(1);
}
void Write_Targa_Line (handle, line_data, line_number)
FILE_HANDLE *handle;
COLOUR *line_data;
int line_number;
{
register int x;
for (x = 0; x < handle->width; x++) {
putc((int) floor (line_data[x].Blue * 255.0), handle->file);
putc((int) floor (line_data[x].Green * 255.0), handle->file);
putc((int) floor (line_data[x].Red * 255.0), handle->file);
}
if (handle->buffer_size == 0) {
fflush(handle->file); /* close and reopen file for */
handle->file = freopen(handle->filename, APPEND_FILE_STRING,
handle->file); /* integrity in case we crash*/
}
}
int Read_Targa_Line (handle, line_data, line_number)
FILE_HANDLE *handle;
COLOUR *line_data;
int *line_number;
{
int x, data;
for (x = 0; x < handle->width; x++) {
/* Read the BLUE data byte. If EOF is reached on the first character read,
then this line hasn't been rendered yet. Return 0. If an EOF occurs
somewhere within the line, this is an error - return -1. */
if ((data = getc(handle->file)) == EOF)
if (x == 0)
return (0);
else
return (-1);
line_data[x].Blue = (DBL) data / 255.0;
/* Read the GREEN data byte. */
if ((data = getc(handle->file)) == EOF)
return (-1);
line_data[x].Green = (DBL) data / 255.0;
/* Read the RED data byte. */
if ((data = getc(handle->file)) == EOF)
return (-1);
line_data[x].Red = (DBL) data / 255.0;
}
*line_number = Targa_Line_Number++;
return(1);
}
void Close_Targa_File (handle)
FILE_HANDLE *handle;
{
if(handle->file)
fclose (handle->file);
if (handle->buffer)
free (handle->buffer);
}
int Read_Targa_Int_Line(handle, line_data)
FILE_HANDLE *handle;
IMAGE_LINE *line_data;
{
int x, data;
if (((line_data->red = (unsigned char *) malloc(handle->width))==NULL) ||
((line_data->green = (unsigned char *) malloc(handle->width))==NULL) ||
((line_data->blue = (unsigned char *) malloc(handle->width))==NULL)) {
fprintf(stderr, "Cannot allocate memory for picture: %s\n",
handle->filename);
close_all();
exit(1);
}
for (x = 0; x < handle->width; x++) {
if ((data = getc(handle->file)) == EOF)
if (x == 0) return (0);
else return (-1);
line_data->blue[x] = data;
if ((data = getc(handle->file)) == EOF) return (-1);
line_data->green[x] = data;
if ((data = getc(handle->file)) == EOF) return (-1);
line_data->red[x] = data;
}
return(1);
}
void
Read_Targa_Image(Image, name)
IMAGE *Image;
char *name;
{
int row;
FILE_HANDLE handle;
if ((handle.file = Locate_File(name, READ_FILE_STRING)) == NULL) {
fprintf (stderr, "Cannot open Targa file %s\n", name);
close_all();
exit(1);
}
Open_Targa_File(&handle, name, &Image->iwidth, &Image->iheight,
0, READ_MODE);
handle.width = Image->iwidth;
handle.height = Image->iheight;
Image->width = (DBL)Image->iwidth;
Image->height = (DBL)Image->iheight;
Image->Colour_Map_Size = 0;
Image->Colour_Map = NULL;
if ((Image->data.rgb_lines = (struct Image_Line *)
malloc(Image->iheight * sizeof (struct Image_Line))) == NULL) {
fprintf (stderr, "Cannot allocate memory for picture: %s\n", name);
exit(1);
}
for (row=0;
row<Image->iheight &&
Read_Targa_Int_Line(&handle, &Image->data.rgb_lines[row]);
row++) {
}
fclose(handle.file);
}